package
{	
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.GradientType;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.Security;
	import flash.system.SecurityDomain;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;
	import flash.utils.getDefinitionByName;
	import flash.utils.getTimer;
	
	[SWF(width=760, height=650,backgroundColor="#ccFFFF",frameRate=30)]
	
	public class BalanceLoaderBase extends Sprite
	{

		
		protected var swfLoader:Loader;
		protected var preloader:MovieClip;
		
		
		protected var app:*;
		
		protected var gameLoadingMode:int = 0;//0 - подарки, 1 - игра
		
		/**
		 * Сылка на объект с флашварсами (должна инициализироваться расширяющим классом)
		 */
		protected var flashVars:Object;
		
		/**
		 * 
		 */
		protected var gameSwfUrl:String;
		
		/**
		 * Ассеты
		 * 0 - ассет с прелоадером
		 */
		public static var assetsSwfUrl:Array;// array of {url, name}
		private var currentLoadableAsset:Object;
		
		protected var assetsAppDomain:Array = [];
		
		/**
		 * Ключ обращения к api (должен задаваться расширяющим классом)
		 */
		protected var key:String;
		
		/**
		 * Сигнализирует о том, что флешка запущена локально
		 */
		protected var DESKTOP_MODE:Boolean = false;
		
		/**
		 * "startPageIndex":1, "talkUserId":2373635
		 */
		public var startSettings:Object;
		
		
		/**
		 * Путь, откуда взята флешка
		 */
		private var swfPath:String;
		
		public static var instance:BalanceLoaderBase;
		
		
		private function get cacheBraker():String
		{
			return "?cb=" + Math.random().toString();
		}
		
		
		public function BalanceLoaderBase()
		{
			tabChildren = false;
			
			Security.allowDomain("*");
			
			super();
			
			assetsSwfUrl = 
				[
					{name:"Preloader.swf", url:"assets/Preloader.swf"}
					,
					{name:"GameAssets.swf", url:"assets/GameAssets.swf"}
					,
					{name:"LoadingUI.swf", url:"assets/LoadingUI.swf"}
				]
				
			gameSwfUrl = "Balance.swf";
			
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			
			
			graphics.beginFill(0x2FADD6);
			graphics.drawRect(0, 0, 760, 650);
		}
	
		
		
		private function onAddedToStage(e:Event):void{
			removeEventListener(e.type, onAddedToStage);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.showDefaultContextMenu = false;
			
			flashVars = loaderInfo && loaderInfo.parameters?loaderInfo.parameters:{};
			
			DESKTOP_MODE = loaderInfo && loaderInfo.url && loaderInfo.url.indexOf("file") != -1;
			
			swfPath = (loaderInfo && loaderInfo.url?(loaderInfo.url.substr(0, loaderInfo.url.lastIndexOf("/") + 1)):"");
			
			CONFIG::debug
			{
				if(DESKTOP_MODE)
				{
					flashVars = new URLVariables("network_user_id=6&secret=4dc01982f8517a304011e9afc5f749c9&first_name=Pav&last_name=&sex=0&photo=null&social=2");
				}
			}
			
			initializeEmbededSWF();
		}
		
		
		protected function initializeEmbededSWF():void
		{
			embededSWFInited();
		}
		
		
		protected function embededSWFInited():void
		{
			// надо загрузить ассет прелоадера, если он не заембежен
			if(ApplicationDomain.currentDomain.hasDefinition("balance.Preloader"))
				onPreloaderAssetLoaded();
			else
				startAssetsLoading();
		}
		
		
		
		protected function onPreloaderAssetLoaded(preloaderMC:MovieClip = null):void
		{
			if(preloaderMC)
				preloader = preloaderMC;
			else
			{
				var preloaderClass:Class = ApplicationDomain.currentDomain.getDefinition("balance.Preloader") as Class;
				preloader = new preloaderClass();
			}
			preloader.x = (stage.stageWidth - 730) * 0.5 + 5;
			preloader.y = (stage.stageHeight - 630) * 0.5 + 5;
			addChild(preloader);
			setProgress(0, 0);
			
			initialize();
		}
		
		
		protected function initialize():void{
			onSocialComplete();
		}
		
		protected function onSocialComplete():void{
			setProgress(0, 1);
			startAssetsLoading();
		}
		
		protected function startAssetsLoading():void
		{
			if(swfLoader == null)
			{
				swfLoader = new Loader();
				swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onAssetsLoaded);
				swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onGameLoadingError);
				swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
			}
			
			currentLoadableAsset = assetsSwfUrl.shift();
			
			if(currentLoadableAsset == null)
			{
				startGameLoading();
				return;
			}
			
			var request:URLRequest = new URLRequest(
				String(DESKTOP_MODE?currentLoadableAsset.name:
					(String(currentLoadableAsset.url).substr(0,7).toLowerCase() == "http://"?
						currentLoadableAsset.url: swfPath + currentLoadableAsset.url) + cacheBraker
			));
			var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, (DESKTOP_MODE?null:SecurityDomain.currentDomain)); 
			
			swfLoader.load(request, context);
		}
		
		
		protected function onAssetsLoaded(e:Object):void
		{
			if(gameLoadingMode > 0) return;
			
			
			var assets:DisplayObjectContainer = e.currentTarget.content as DisplayObjectContainer;
			assetsAppDomain[currentLoadableAsset.name] = assets.loaderInfo.applicationDomain;
			
			
			if(preloader)
			{
				// если прелоадер уже был загружен, предпринимаем следующие шаги загрузки
				if(assetsSwfUrl.length)
				{
					startAssetsLoading();
				}
				else
				{
					swfLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onAssetsLoaded);
					gameLoadingMode++;
					startGameLoading();
				}
			}else{
				// видимо мы загрузили долгожданный ассет прелоадера
				onPreloaderAssetLoaded(e.target.content);
			}
		}
		
		
		protected function startGameLoading():void
		{
			try{
				var cl:Class = getDefinitionByName("Balance") as Class;
			}catch(e:Error){}
			if(cl)
			{
				onGameLoaded({"currentTarget":{"content":new cl()}});
				return;
			}
			var request:URLRequest = new URLRequest(
				String(DESKTOP_MODE?"Balance.swf":(gameSwfUrl.substr(0,7).toLowerCase() == "http://"?gameSwfUrl: swfPath + gameSwfUrl)) + cacheBraker
			);
			var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, (DESKTOP_MODE?null:SecurityDomain.currentDomain)); 
			swfLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onAssetsLoaded);
			swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onGameLoaded);
			swfLoader.load(request, context);
		}
		
		/**
		 * Очистка для GC
		 */
		public function clear():void{
			if(swfLoader){
				swfLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onGameLoaded);
				swfLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onGameLoadingError);
				swfLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
			}
			
			if(preloader){
				preloader.stop();
				removeChild(preloader)
				preloader = null;
			}
			
		}
		
		
		/**
		 * Приложение не может быть загружено
		 */
		private function onGameLoadingError(e:IOErrorEvent):void{
			trace("onGameLoadingError");
		}
		
		/**
		 * Приоложение загружается
		 */
		private function onProgress(e:ProgressEvent):void{
			if(preloader)
			{
				var persent:String = int(e.bytesLoaded/e.bytesTotal * 100) + "%";
				// и куда нить подставить
				setProgress(1 + gameLoadingMode, e.bytesLoaded/e.bytesTotal);
			}
		}
		
		/**
		 * Установить прогресс прелоадера
		 * 0 соц. сеть
		 * 1 продарки
		 * 2 игра
		 */
		private function setProgress(type:int, value:Number):void
		{
			if(preloader)
			{
				var result:Number = 0;
				if(type == 0) result = 0.2 * value;
				else if (type == 1) result = 0.2 + 0.2 * value;
				else if (type == 2) result = 0.4 + 0.6 * value;
				else result = 1;
				preloader.gotoAndStop(int(100 * result));
			}
		}
		
		/**
		 * Приложене было загружено
		 */
		private function onGameLoaded(e:Object):void{
			clear();
			
			app = e.currentTarget.content;
			
			addChild(app);
			app.run(flashVars);
		}
		
		
		
	}
}